using System;
namespace Organized
{
    public class Component
    {
        // The GameScreen object that owns this component
        public GameScreen Parent;

        // Whether or not this component has been initialized
        public bool Initialized = false;

        // Whether or not the GameScreen that owns the component
        // should draw it
        public bool Visible = true;

        // The draw order of the component. Lower values draw first
        int drawOrder = 1;

        // Draw order changed event
        public event ComponentDrawOrderChangedEventHandler DrawOrderChanged;

        // Public draw order. If the value is changed, we fire the draw
        // order change event
        public int DrawOrder
        {
            get { return drawOrder; }
            set
            {
                // Save a copy of the old value and set the new one
                int last = drawOrder;
                drawOrder = value;

                // Fire DrawOrderChanged
                if (DrawOrderChanged != null)
                    DrawOrderChanged(this,
                        new ComponentDrawOrderChangedEventArgs(
                            this, last, this.Parent.Components));
            }
        }

        // This overloaded constructor allows us to specify the parent
        public Component(GameScreen Parent)
        {
            InitializeComponent(Parent);
        }

        // This overload allows will set the parent to the default
        // GameScreen
        public Component()
        {
            InitializeComponent(Engine.DefaultScreen);
        }

        // This is called by the constructor to initialize the
        // component. This allows us to only have to override this
        // method instead of both constructors
        protected virtual void InitializeComponent(GameScreen Parent)
        {
            // Check if the engine has been initialized before setting
            // up the component, or the Engine will crash when the
            // component tries to add itself to the list.
            if (!Engine.IsInitialized)
                throw new Exception("Engine must be initialized with \"SetupEngine()\""
                    + "before components can be initialized");

            Parent.Components.Add(this);
            Initialized = true;
        }

        // Updates the component - This is called by the owner
        public virtual void Update()
        {
        }


        // Draws the component - This is called by the owner
        public virtual void Draw()
        {
        }

        // Unregisters the component with its parent
        public virtual void DisableComponent()
        {
            Parent.Components.Remove(this);
        }
    }

    // Event arguments for draw order change on a component
    public class ComponentDrawOrderChangedEventArgs : EventArgs
    {
        // Component that was modified
        public Component Component;

        // The old draw order
        public int LastDrawOrder;

        // The collection that owns the component
        public ComponentCollection ParentCollection;

        public ComponentDrawOrderChangedEventArgs(Component Component,
            int LastDrawOrder, ComponentCollection ParentCollection)
        {
            this.Component = Component;
            this.LastDrawOrder = LastDrawOrder;
            this.ParentCollection = ParentCollection;
        }
    }

    // Event handler for draw order change on a component
    public delegate void ComponentDrawOrderChangedEventHandler(
        object sender, ComponentDrawOrderChangedEventArgs e);
}